#ifndef CANREAPER_H
#define CANREAPER_H

#include "Logger.h"

#include "BS_thread_pool.hpp"

struct can_frame;

namespace canpp {
    static BS::thread_pool<> pool;

    class CanReader;
    using std::shared_ptr;
    using std::jthread;
    using std::vector;
    using std::string;
    using std::unordered_map;
    using std::unordered_multimap;

    using bq::log;


    class CanReaper {
    public:
        CanReaper(const CanReaper &obj) = delete;

        CanReaper &operator=(const CanReaper &obj) = delete;

        ~CanReaper();

        static CanReaper &getInstance();

        //TODO: Use shared_ptr for reader
        void bindReader(CanReader *reader, const string &canInterface);

        //TODO: Use shared_ptr for reader
        void removeReader(const CanReader *reader);

        int createOrGetInterfaceFd(const string &canInterface);

        void cleanUp();

    private:
        CanReaper();

        log logger;

        jthread reap_thread;

        void reap_process(const std::stop_token &stop_token);

        int open_can_socket(const string &canInterface) const;

        int open_interface(const string &canInterface) const;

        unordered_map<int, string> interfaces{};
        unordered_multimap<int, CanReader *> readers;

        int epoll_fd;

        int new_sock_event_fd;
    };
} // canpp

#endif //CANREAPER_H
